package cn.lili.modules.order.order.serviceimpl;

import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.DateUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.order.aftersale.service.AfterSaleService;
import cn.lili.modules.order.aftersale.service.AfterSaleStatisticsService;
import cn.lili.modules.order.order.entity.dos.OrderItemFlow;
import cn.lili.modules.order.order.entity.dto.OrderFlowQueryDTO;
import cn.lili.modules.order.order.entity.dto.OrderStatisticsSearchParams;
import cn.lili.modules.order.order.entity.vo.OrderFlowStatisticsVO;
import cn.lili.modules.order.order.mapper.OrderFlowStatisticsMapper;
import cn.lili.modules.order.order.service.OrderFlowStatisticsService;
import cn.lili.modules.order.order.service.OrderStatisticsService;
import cn.lili.modules.statistics.entity.dto.GoodsStatisticsQueryParam;
import cn.lili.modules.statistics.entity.dto.StatisticsQueryParam;
import cn.lili.modules.statistics.entity.enums.StatisticsQuery;
import cn.lili.modules.statistics.entity.vo.CategoryStatisticsDataVO;
import cn.lili.modules.statistics.entity.vo.GoodsStatisticsDataVO;
import cn.lili.modules.statistics.entity.vo.OrderOverviewVO;
import cn.lili.modules.statistics.entity.vo.StoreStatisticsDataVO;
import cn.lili.modules.statistics.util.StatisticsDateUtil;
import cn.lili.modules.store.client.StoreClient;
import cn.lili.modules.store.entity.dos.Store;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品统计业务层实现
 *
 * @author Bulbasaur
 * @since 2020/12/9 11:30
 */
@Service
@RequiredArgsConstructor
public class OrderFlowStatisticsServiceImpl extends ServiceImpl<OrderFlowStatisticsMapper, OrderItemFlow> implements OrderFlowStatisticsService {

    private final OrderStatisticsService orderStatisticsService;

    private final StoreClient storeClient;

    private final AfterSaleStatisticsService afterSaleStatisticsService;

    @Override
    public List<GoodsStatisticsDataVO> getGoodsStatisticsData(GoodsStatisticsQueryParam goodsStatisticsQueryParam, Integer num) {
        //获取查询条件
        QueryWrapper queryWrapper = getQueryWrapper(goodsStatisticsQueryParam);
        //根据商品分组
        queryWrapper.groupBy("goods_id");
        queryWrapper.groupBy("goods_name");

        queryWrapper.eq(CharSequenceUtil.isNotEmpty(goodsStatisticsQueryParam.getStoreId()), "store_id", goodsStatisticsQueryParam.getStoreId());
        //查询前X记录
        Page page = new Page<GoodsStatisticsDataVO>(1, num);
        List<GoodsStatisticsDataVO> o = this.baseMapper.getGoodsStatisticsData(page, queryWrapper);
        return o;
    }

    @Override
    public List<CategoryStatisticsDataVO> getCategoryStatisticsData(GoodsStatisticsQueryParam goodsStatisticsQueryParam) {
        //获取查询条件
        QueryWrapper queryWrapper = getQueryWrapper(goodsStatisticsQueryParam);
        //根据分类分组
        queryWrapper.groupBy("category_id");
        return this.baseMapper.getCateGoryStatisticsData(queryWrapper);
    }

    @Override
    public List<StoreStatisticsDataVO> getStoreStatisticsData(Page page, QueryWrapper queryWrapper) {
        return this.baseMapper.getStoreStatisticsData(page, queryWrapper);
    }

    @Override
    public Map<String, Object> getOrderStatisticsPrice(String storeId) {
        QueryWrapper queryWrapper = Wrappers.query();
        //商家查询，则增加商家判定
        if (CharSequenceUtil.isNotEmpty(storeId)) {
            queryWrapper.eq("store_id", storeId);
        }
        //大于今天凌晨
        queryWrapper.ge("create_time", DateUtil.startOfTodDayTime());

        queryWrapper.select("SUM(flow_price) AS price , COUNT(0) AS num");
        return this.getMap(queryWrapper);
    }


    @Override
    public void overview(Date[] dates, OrderOverviewVO orderOverviewVO, StatisticsQueryParam statisticsQueryParam) {
        //下单统计
        initOrder(dates, orderOverviewVO, statisticsQueryParam);

        //付款统计
        initPayment(dates, orderOverviewVO, statisticsQueryParam);

        //退单统计
        afterSaleStatisticsService.initAfterSale(dates, orderOverviewVO, statisticsQueryParam);
    }

    @Override
    public OrderFlowStatisticsVO staticsByQueryParams(OrderFlowQueryDTO queryDTO) {

        if (queryDTO.getEndDate() == null || queryDTO.getStartDate() == null) {
            throw new ServiceException("请指定统计周期");
        }

        //限制查询参数
        switch (UserContext.getCurrentUser().getScene()) {
            case STORE -> queryDTO.setStoreId(UserContext.getCurrentUser().getExtendId());
            case SUPPLIER -> queryDTO.setSupplierSearch(true);
            case URBAN_SUBSTATION -> {
                List<Store> storeList = storeClient.getSupplierListByUrbanId(UserContext.getCurrentUser().getId());
                if (!storeList.isEmpty()) {
                    queryDTO.setStoreIds(storeList.stream().map(Store::getId).toList());
                }
            }
        }


        //统计全部
        OrderFlowStatisticsVO orderFlowStatisticsVO = baseMapper.statistics(queryDTO.generatorQueryWrapper());

        //统计一结算
        queryDTO.setIsProfitSharing(true);

        OrderFlowStatisticsVO settled = baseMapper.statistics(queryDTO.generatorQueryWrapper());

        //写入结算信息
        orderFlowStatisticsVO.setSettledOrderFlow(settled);

        return orderFlowStatisticsVO.filter();
    }

    @Override
    public Map<String, Object> getOrderStatisticsPriceByUrban(String storeId) {
        QueryWrapper queryWrapper = Wrappers.query();
        List<Store> storeList = storeClient.getSupplierListByUrbanId(UserContext.getCurrentUser().getId());
        if (!storeList.isEmpty()) {
            List<String> storeIds = storeList.stream().map(Store::getId).collect(Collectors.toList());
            queryWrapper.in("supplier_id", storeIds);
        }else {
            queryWrapper.eq("supplier_id", "");
        }
        //大于今天凌晨
        queryWrapper.ge("create_time", DateUtil.startOfTodDayTime());

        queryWrapper.select("SUM(flow_price) AS price , COUNT(0) AS num");
        return this.getMap(queryWrapper);
    }

    /**
     * 订单统计-下单属性填充
     *
     * @param dates
     * @param orderOverviewVO
     */
    private void initOrder(Date[] dates, OrderOverviewVO orderOverviewVO, StatisticsQueryParam statisticsQueryParam) {
        //构建查询条件
        OrderStatisticsSearchParams searchParams = new OrderStatisticsSearchParams();
        searchParams.setDates(dates);
        searchParams.setStoreId(statisticsQueryParam.getStoreId());
        //获取查询结果
        Map<String, Object> order = orderStatisticsService.getMap(searchParams.getQueryWrapper());
        //赋予订单数和流水金额
        orderOverviewVO.setOrderNum(order != null && order.containsKey("num") ? (Long) order.get("num") : 0L);
        orderOverviewVO.setOrderAmount(order != null && order.containsKey("price") ? CurrencyUtil.convertDouble(order.get("price").toString()) : 0L);

        //查询下单人数
        QueryWrapper queryWrapper = new QueryWrapper();
        //时间区间
        queryWrapper.between("create_time", dates[0], dates[1]);
        //如果有店铺id传入，则查询店铺
        if (StringUtils.isNotEmpty(statisticsQueryParam.getStoreId())) {
            queryWrapper.eq("store_id", statisticsQueryParam.getStoreId());
        }
        //查询下单人数的sql
        queryWrapper.select("count(DISTINCT user_id) AS num");
        //获取查询结果
        Map memberNum = this.getMap(queryWrapper);
        //写入下单人数
        orderOverviewVO.setOrderMemberNum(memberNum != null && memberNum.containsKey("num") ? (Long) memberNum.get("num") : 0L);
    }

    /**
     * 订单统计-付款属性填充
     *
     * @param dates
     * @param orderOverviewVO
     */
    private void initPayment(Date[] dates, OrderOverviewVO orderOverviewVO, StatisticsQueryParam statisticsQueryParam) {
        //付款订单数，付款金额
        QueryWrapper queryWrapper = Wrappers.query();
        queryWrapper.between("create_time", dates[0], dates[1]);
        //如果有店铺id传入，则查询店铺
        if (StringUtils.isNotEmpty(statisticsQueryParam.getStoreId())) {
            queryWrapper.eq("store_id", statisticsQueryParam.getStoreId());
        }
        queryWrapper.select("SUM(flow_price) AS price , COUNT(0) AS num");
        queryWrapper.eq("is_pay", true);
        Map payment = this.getMap(queryWrapper);

        orderOverviewVO.setPaymentOrderNum(payment != null && payment.containsKey("num") ? (Long) payment.get("num") : 0L);
        orderOverviewVO.setPaymentAmount(payment != null && payment.containsKey("price") ?
                CurrencyUtil.convertDouble(payment.get("price").toString()) : 0D);

        //如果有店铺id传入，则查询店铺
        if (CharSequenceUtil.isNotEmpty(statisticsQueryParam.getStoreId())) {
            orderOverviewVO.setPaymentsNum(baseMapper.countPayersByStore(statisticsQueryParam.getStoreId(), dates[0], dates[1]));
        } else {
            orderOverviewVO.setPaymentsNum(baseMapper.countPayers(dates[0], dates[1]));
        }
    }

    /**
     * 订单统计-付款属性填充
     *
     * @param dates
     * @param orderOverviewVO
     */
    private void initAfterSale(Date[] dates, OrderOverviewVO orderOverviewVO, StatisticsQueryParam statisticsQueryParam) {
        //付款订单数，付款金额
        QueryWrapper queryWrapper = Wrappers.query();
        queryWrapper.between("create_time", dates[0], dates[1]);
        queryWrapper.select("SUM(refund_price) AS price , COUNT(0) AS num");
        //如果有店铺id传入，则查询店铺
        if (CharSequenceUtil.isNotEmpty(statisticsQueryParam.getStoreId())) {
            queryWrapper.eq("store_id", statisticsQueryParam.getStoreId());
        }
        queryWrapper.eq("is_pay", true);
        queryWrapper.gt("refund_price", 0);
        Map payment = this.getMap(queryWrapper);
        orderOverviewVO.setRefundOrderNum(payment != null && payment.containsKey("num") ? (Long) payment.get("num") : 0L);
        orderOverviewVO.setRefundOrderPrice(payment != null && payment.containsKey("price") ?
                CurrencyUtil.convertDouble(payment.get("price").toString()) : 0D);
    }


    /**
     * 组织查询条件
     *
     * @param goodsStatisticsQueryParam
     * @return
     */
    private QueryWrapper getQueryWrapper(GoodsStatisticsQueryParam goodsStatisticsQueryParam) {

        QueryWrapper queryWrapper = Wrappers.query();
        //判断搜索类型是：年、月
        Date[] date = StatisticsDateUtil.getDateArray(goodsStatisticsQueryParam);
        queryWrapper.between("create_time", date[0], date[1]);

        //判断是按照数量统计还是按照金额统计
        if (goodsStatisticsQueryParam.getType().equals(StatisticsQuery.PRICE.name())) {
            queryWrapper.orderByDesc("price");
        } else {
            queryWrapper.orderByDesc("num");
        }
        //设置为付款查询
        queryWrapper.eq("is_pay", true);
        return queryWrapper;
    }

}
